/**
 * Util模块 - 实用工具函数
 * 借鉴Lodash的Util理念
 */

// 用于生成唯一ID的计数器
let idCounter = 0;

/**
 * 执行函数n次
 * @param {number} n 执行次数
 * @param {Function} iteratee 迭代函数
 * @returns {Array} 执行结果数组
 */
export function times(n, iteratee) {
  if (typeof n !== 'number' || n < 0) return [];
  if (typeof iteratee !== 'function') iteratee = (i) => i;

  const result = [];
  for (let i = 0; i < n; i++) {
    result.push(iteratee(i));
  }
  return result;
}

/**
 * 生成唯一ID
 * @param {string} prefix 前缀
 * @returns {string} 唯一ID
 */
export function uniqueId(prefix = '') {
  idCounter++;
  return prefix + idCounter;
}

/**
 * 生成范围数组
 * @param {number} start 起始值
 * @param {number} end 结束值
 * @param {number} step 步长
 * @returns {Array} 范围数组
 */
export function range(start = 0, end, step = 1) {
  // 如果只有一个参数，则从0开始到该参数
  if (end === undefined) {
    end = start;
    start = 0;
  }

  if (step === 0) return [];

  const result = [];
  const isDescending = step < 0;

  if (isDescending) {
    for (let i = start; i > end; i += step) {
      result.push(i);
    }
  } else {
    for (let i = start; i < end; i += step) {
      result.push(i);
    }
  }

  return result;
}

/**
 * 从右向左生成范围数组
 * @param {number} start 起始值
 * @param {number} end 结束值
 * @param {number} step 步长
 * @returns {Array} 范围数组（逆序）
 */
export function rangeRight(start = 0, end, step = 1) {
  return range(start, end, step).reverse();
}

/**
 * 尝试执行函数，返回结果或错误
 * @param {Function} func 要执行的函数
 * @param {...any} args 参数
 * @returns {any} 执行结果或Error对象
 */
export function attempt(func, ...args) {
  try {
    return func(...args);
  } catch (error) {
    return error;
  }
}

/**
 * 返回默认值（如果值为null、undefined或NaN）
 * @param {any} value 值
 * @param {any} defaultValue 默认值
 * @returns {any} 值或默认值
 */
export function defaultTo(value, defaultValue) {
  return value == null || value !== value ? defaultValue : value;
}

/**
 * 创建一个返回指定值的函数
 * @param {any} value 要返回的值
 * @returns {Function} 常量函数
 */
export function constant(value) {
  return function() {
    return value;
  };
}

/**
 * 身份函数（返回第一个参数）
 * @param {any} value 输入值
 * @returns {any} 输入值本身
 */
export function identity(value) {
  return value;
}

/**
 * 空操作函数
 */
export function noop() {
  // 什么都不做
}

/**
 * 始终返回true的函数
 * @returns {boolean} true
 */
export function stubTrue() {
  return true;
}

/**
 * 始终返回false的函数
 * @returns {boolean} false
 */
export function stubFalse() {
  return false;
}

/**
 * 始终返回空数组的函数
 * @returns {Array} 空数组
 */
export function stubArray() {
  return [];
}

/**
 * 始终返回空对象的函数
 * @returns {Object} 空对象
 */
export function stubObject() {
  return {};
}

/**
 * 始终返回空字符串的函数
 * @returns {string} 空字符串
 */
export function stubString() {
  return '';
}

/**
 * 创建迭代器函数
 * @param {Function|Object|Array|string} value 值
 * @returns {Function} 迭代器函数
 */
export function iteratee(value) {
  if (typeof value === 'function') {
    return value;
  }

  if (value == null) {
    return identity;
  }

  if (typeof value === 'object') {
    if (Array.isArray(value)) {
      // 如果是数组 [key, value]，创建匹配函数
      return (obj) => obj[value[0]] === value[1];
    }
    // 如果是对象，创建匹配函数
    return (obj) => {
      return Object.keys(value).every(key => obj[key] === value[key]);
    };
  }

  // 如果是字符串，创建属性访问器
  if (typeof value === 'string') {
    return (obj) => obj[value];
  }

  return identity;
}

/**
 * 创建匹配器函数
 * @param {Object} source 源对象
 * @returns {Function} 匹配器函数
 */
export function matches(source) {
  return (obj) => {
    if (obj === source) return true;
    if (source == null || obj == null) return obj === source;

    return Object.keys(source).every(key => obj[key] === source[key]);
  };
}

/**
 * 创建属性匹配器函数
 * @param {string} path 属性路径
 * @param {any} srcValue 源值
 * @returns {Function} 匹配器函数
 */
export function matchesProperty(path, srcValue) {
  return (obj) => {
    if (!obj) return false;

    // 简单路径处理
    const keys = path.split('.');
    let value = obj;

    for (const key of keys) {
      if (value == null) return false;
      value = value[key];
    }

    return value === srcValue;
  };
}

/**
 * 创建属性访问器函数
 * @param {string} path 属性路径
 * @returns {Function} 访问器函数
 */
export function property(path) {
  return (obj) => {
    if (!obj) return undefined;

    // 简单路径处理
    const keys = path.split('.');
    let value = obj;

    for (const key of keys) {
      if (value == null) return undefined;
      value = value[key];
    }

    return value;
  };
}

/**
 * 创建属性设置器函数
 * @param {string} path 属性路径
 * @returns {Function} 设置器函数
 */
export function propertyOf(obj) {
  return (path) => {
    if (!obj) return undefined;

    const keys = path.split('.');
    let value = obj;

    for (const key of keys) {
      if (value == null) return undefined;
      value = value[key];
    }

    return value;
  };
}

/**
 * 方法调用器
 * @param {string} path 方法路径
 * @param {...any} args 参数
 * @returns {Function} 调用器函数
 */
export function method(path, ...args) {
  return (obj) => {
    if (!obj) return undefined;

    const keys = path.split('.');
    let value = obj;

    for (let i = 0; i < keys.length - 1; i++) {
      if (value == null) return undefined;
      value = value[keys[i]];
    }

    const methodName = keys[keys.length - 1];
    const method = value && value[methodName];

    if (typeof method === 'function') {
      return method.apply(value, args);
    }

    return undefined;
  };
}

/**
 * 对象方法调用器
 * @param {Object} object 对象
 * @param {...any} args 参数
 * @returns {Function} 调用器函数
 */
export function methodOf(object, ...args) {
  return (path) => {
    if (!object) return undefined;

    const keys = path.split('.');
    let value = object;

    for (let i = 0; i < keys.length - 1; i++) {
      if (value == null) return undefined;
      value = value[keys[i]];
    }

    const methodName = keys[keys.length - 1];
    const method = value && value[methodName];

    if (typeof method === 'function') {
      return method.apply(value, args);
    }

    return undefined;
  };
}

/**
 * 创建符合规范检查器
 * @param {Object} source 规范对象
 * @returns {Function} 检查器函数
 */
export function conforms(source) {
  return (obj) => {
    if (obj === source) return true;
    if (!obj || !source) return false;

    return Object.keys(source).every(key => {
      const predicate = source[key];
      if (typeof predicate === 'function') {
        return predicate(obj[key]);
      }
      return obj[key] === predicate;
    });
  };
}

/**
 * 检查对象是否符合规范
 * @param {Object} obj 要检查的对象
 * @param {Object} source 规范对象
 * @returns {boolean} 是否符合
 */
export function conformsTo(obj, source) {
  return conforms(source)(obj);
}

/**
 * 混合函数
 * @param {Object} object 目标对象
 * @param {...Object} sources 源对象
 * @returns {Object} 目标对象
 */
export function mixin(object, ...sources) {
  sources.forEach(source => {
    if (source) {
      Object.keys(source).forEach(key => {
        if (typeof source[key] === 'function') {
          object[key] = source[key];
        }
      });
    }
  });

  return object;
}

/**
 * 运行函数并返回对象
 * @param {any} value 值
 * @param {Function} interceptor 拦截器函数
 * @returns {any} 原值
 */
export function tap(value, interceptor) {
  if (typeof interceptor === 'function') {
    interceptor(value);
  }
  return value;
}

/**
 * 运行函数并返回函数结果
 * @param {any} value 值
 * @param {Function} interceptor 拦截器函数
 * @returns {any} 函数返回值
 */
export function thru(value, interceptor) {
  if (typeof interceptor === 'function') {
    return interceptor(value);
  }
  return value;
}

/**
 * 转换为路径数组
 * @param {string} path 路径字符串
 * @returns {string[]} 路径数组
 */
export function toPath(path) {
  if (Array.isArray(path)) return path;
  if (typeof path !== 'string') return [];

  const result = [];
  let current = '';
  let inBracket = false;

  for (let i = 0; i < path.length; i++) {
    const char = path[i];

    if (char === '[') {
      if (current) {
        result.push(current);
        current = '';
      }
      inBracket = true;
    } else if (char === ']') {
      if (current) {
        result.push(current);
        current = '';
      }
      inBracket = false;
    } else if (char === '.' && !inBracket) {
      if (current) {
        result.push(current);
        current = '';
      }
    } else {
      current += char;
    }
  }

  if (current) {
    result.push(current);
  }

  return result;
}

/**
 * 生成随机值
 * @param {number} lower 下限
 * @param {number} upper 上限
 * @param {boolean} floating 是否浮点数
 * @returns {number} 随机值
 */
export function random(lower = 0, upper = 1, floating = false) {
  // 参数调整
  if (upper === undefined) {
    upper = lower;
    lower = 0;
  }

  if (floating || lower % 1 !== 0 || upper % 1 !== 0) {
    return Math.random() * (upper - lower) + lower;
  }

  return Math.floor(Math.random() * (upper - lower + 1)) + lower;
}

/**
 * 限制数字在范围内
 * @param {number} number 数字
 * @param {number} lower 下限
 * @param {number} upper 上限
 * @returns {number} 限制后的数字
 */
export function clamp(number, lower, upper) {
  if (upper === undefined) {
    upper = lower;
    lower = undefined;
  }

  if (lower !== undefined && number < lower) {
    return lower;
  }

  if (upper !== undefined && number > upper) {
    return upper;
  }

  return number;
}

/**
 * 检查数字是否在范围内
 * @param {number} number 数字
 * @param {number} start 起始值
 * @param {number} end 结束值
 * @returns {boolean} 是否在范围内
 */
export function inRange(number, start = 0, end) {
  if (end === undefined) {
    end = start;
    start = 0;
  }

  if (start > end) {
    [start, end] = [end, start];
  }

  return number >= start && number < end;
}

/**
 * 转义正则表达式特殊字符
 * @param {string} str 字符串
 * @returns {string} 转义后的字符串
 */
export function escapeRegExp(str) {
  if (typeof str !== 'string') return '';
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

/**
 * 延迟执行
 * @param {Function} func 函数
 * @param {number} wait 等待时间
 * @param {...any} args 参数
 * @returns {number} 定时器ID
 */
export function delay(func, wait = 0, ...args) {
  if (typeof func !== 'function') {
    throw new TypeError('Expected a function');
  }

  return setTimeout(() => func(...args), wait);
}

/**
 * 绑定方法到对象
 * @param {Object} object 对象
 * @param {...string} methodNames 方法名
 * @returns {Object} 对象
 */
export function bindAll(object, ...methodNames) {
  methodNames.forEach(key => {
    if (typeof object[key] === 'function') {
      object[key] = object[key].bind(object);
    }
  });

  return object;
}

/**
 * 创建范围内的随机整数
 * @param {number} min 最小值
 * @param {number} max 最大值
 * @returns {number} 随机整数
 */
export function randomInt(min = 0, max = 100) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

/**
 * 版本号
 * @returns {string} 版本号
 */
export function VERSION() {
  return '1.0.0';
}

/**
 * 空值检查
 * @param {any} value 值
 * @returns {boolean} 是否为空
 */
export function isNil(value) {
  return value == null;
}
